package com.bs.controller;

import com.bs.bean.*;
import com.bs.service.CommentService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.bs.service.VideoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;


@Controller
public class VideoController {

    @Autowired
    private VideoService videoService;

    @Autowired
    private CommentService commentService;

    @Value("${uploadPath}")
    private String uploadPath;
    public VideoController(){

    }

    @PostMapping(value = "/videoUpload")
    public String videoUpload(String title,String type, MultipartFile file, HttpServletRequest request, HttpSession session) throws IOException {
        String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));

        if(!extName.equals(".mp4")){
            return "frontPage/videoUploadFailed";
        }else{
            Video video = new Video();
            String videoName = file.getOriginalFilename();  //获取上传后的文件名
            // String newVideoName = this.getName(videoName);  //根据上传的文件名重新生成一份新的文件名
//        String path = request.getServletContext().getRealPath("video");
//            String path = "D:/upload/video/";
            String path = uploadPath;
            File videoPath = new File(path, videoName);

            if (!videoPath.getParentFile().exists()) {
                videoPath.getParentFile().mkdirs();
            }


            file.transferTo(videoPath);

            User user = (User) session.getAttribute("user");
            video.setAuthor(user.getUsername());
            video.setPath("/video/" + videoName);
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            video.setUploadTime(timestamp);
            video.setTitle(title);
            video.setSize(this.getSize(videoPath));
            video.setType(this.getFileExt(videoName));
            Integer typeId = videoService.selectTypeIdByName(type);
            video.setTypeId(typeId);
            boolean result = videoService.addVideo(video);
            if (result ) {
                return "frontPage/uploadSuccess";
            }else{
                return "frontPage/videoUploadFailed";
            }
        }
    }

    @GetMapping(value = "/getVideoByName")
    public String getTopicByName(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                 String title,ModelMap model) {
        PageHelper.startPage(pageNum,5);
        PageHelper.orderBy("uploadTime desc");
        List<Video> list = videoService.getVideoByName(title);

        PageInfo pageInfo = new PageInfo(list);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo",pageInfo);
        model.addAttribute("type",0);
        model.addAttribute("title", title);
        return "frontPage/videoList";
    }


    @GetMapping(value = "/getVideoListRecord")
    public String getVideoListRecord( @RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model,HttpSession session) {
        User user= (User)session.getAttribute("user");
        String username = user.getUsername();
        PageHelper.startPage(num, 5);
//        PageHelper.orderBy("num desc");
        List<Video> videoList = videoService.getVideoListRecord(username);

        PageInfo pageInfo = new PageInfo(videoList);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 8);
        return "frontPage/videoList";
    }


    @GetMapping(value = "/getVideoListByAuthor")
    public String getVideoListByAuthor(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                 ModelMap model,HttpSession session) {
        Integer videoId = (Integer)session.getAttribute("videoId");
        Video video = videoService.getVideoById(videoId);
        String author = video.getAuthor();

        PageHelper.startPage(pageNum,5);
        PageHelper.orderBy("uploadTime desc");
        List<Video> list = videoService.getVideoListByAuthor(author);

        PageInfo pageInfo = new PageInfo(list);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo",pageInfo);
        model.addAttribute("type",5);
        return "frontPage/videoList";
    }

    @GetMapping(value = "/getVideoListByType")
    public String getVideoListByType( String value, @RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        Integer typeId = videoService.selectTypeIdByName(value);
        PageHelper.startPage(num, 5);
        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getVideoListByType(typeId);

        PageInfo pageInfo = new PageInfo(videoList);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 6);
        return "frontPage/videoList";
    }

    @GetMapping(value = "/getOtherVideoListByType")
    public String getOtherVideoListByType(  @RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model,HttpSession session) {
        Integer videoId = (Integer)session.getAttribute("videoId");
        PageHelper.startPage(num, 5);
//        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getOtherVideoListByType(videoId);

        PageInfo pageInfo = new PageInfo(videoList);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 7);
        return "frontPage/videoList";
    }

//    //网站前台
//    @GetMapping(value = "/getNewsById")
//    public String getNewsById(Integer id,ModelMap model) {
//        News news = newService.getNewsById(id);
//        if(news!=null){
//            model.addAttribute("news",news);
//        }
//        return "news";
//    }

    //普通用户猜你喜欢
    @GetMapping(value = "/getVideoListOfLike")
    public String getVideoListOfLike(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model,HttpSession session) {
        User user = (User) session.getAttribute("user");
        String username = user.getUsername();
//        PageHelper.startPage(num, 5);
//        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getVideoListOfLike(username);

        PageInfo pageInfo = new PageInfo(videoList);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 10);
        return "frontPage/videoList";
    }

    //普通用户最新视频
    @GetMapping(value = "/getVideoListByUser")
    public String getVideoListByUser(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        PageHelper.startPage(num, 5);
        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getVideoList();

        PageInfo pageInfo = new PageInfo(videoList);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 1);
        return "frontPage/videoList";
    }

    //普通用户最热视频
    @GetMapping(value = "/getVideoListByHeat")
    public String getVideoListByHeat(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        PageHelper.startPage(num, 5);
//        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getVideoListByHeat();

        PageInfo pageInfo = new PageInfo(videoList);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 2);
        return "frontPage/videoList";
    }

    //普通用户查看系统推送视频
    @GetMapping(value = "/getVideoListBySystem")
    public String getVideoListBySystem(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        PageHelper.startPage(num, 5);
        PageHelper.orderBy("pushTime desc");
        List<Video> videoList = videoService.getVideoListBySystem();

        PageInfo pageInfo = new PageInfo(videoList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 3);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        return "frontPage/videoList";
    }

    @GetMapping(value = "/getVideoListByOnly")
    public String getVideoListByOnly(Integer videoId,@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model,HttpSession session) {
        PageHelper.startPage(num, 5);
//        PageHelper.orderBy("uploadTime desc");
//        Video video = videoService.getVideoById(videoId);
        User user = (User) session.getAttribute("user");
        VideoClick videoClick = new VideoClick();
        videoClick.setUsername(user.getUsername());
        videoClick.setVideoId(videoId);
        List<Video> videoList1 = videoService.getVideoListByOnly(videoClick);
        PageInfo pageInfo = new PageInfo(videoList1);
        List<VideoType> videoTypeList = videoService.getOneType();
        model.addAttribute("types", videoTypeList);
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("type", 4);
        model.addAttribute("videoId", videoId);
        return "frontPage/videoList";
    }

    //用户点击播放按钮，开始播放视频
    @GetMapping(value = "/videoPlayById")
    public String videoPlayById(Integer id, ModelMap model, HttpSession session) {

        User user = (User) session.getAttribute("user");
        Video video = videoService.getVideoById(id);
        model.addAttribute("title", video.getTitle());
        model.addAttribute("path", video.getPath());
        model.addAttribute("video_id", video.getId());
        session.setAttribute("videoId",video.getId());
        videoService.addVideoVv(id);

        VideoClick videoClick = new VideoClick();
        videoClick.setUsername(user.getUsername());
        videoClick.setVideoId(id);
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        videoClick.setUpdateTime(timestamp);

        Integer num = videoService.selectVideoClick(videoClick);
        if(num != 1){
            videoService.addVideoClick(videoClick);
        }else{
            videoService.addVideoClickNum(videoClick);
        }
        List<Comment> comments = commentService.listByIdComment(id);
        model.addAttribute("videoId", id);
        model.addAttribute("comments", comments);

        return "frontPage/videoPlay";


    }

    //管理员
    @GetMapping(value = "/getVideoByNameByAdmin")
    public String getVideoByNameByAdmin(@RequestParam(value = "pageNum",defaultValue = "1")Integer pageNum,
                                        String title,ModelMap model) {
        PageHelper.startPage(pageNum,5);
        PageHelper.orderBy("uploadTime desc");
        List<Video> list = videoService.getVideoByName(title);

        PageInfo pageInfo = new PageInfo(list);
        model.addAttribute("pageInfo",pageInfo);
        return "admin/video/videoList";
    }



    @PostMapping(value = "/videoAddType")
    public String videoAddType(String type,ModelMap model ) {
        if(type!=null){
            VideoType videoType = videoService.getTypeBySTypeName(type);
            if(videoType==null){
                VideoType videoType1 = new VideoType();
                videoType1.setTypeName(type);
                videoService.addTypeByTypeName(videoType1);
                return "admin/uploadSuccess";
            }else{
                model.addAttribute("error","已有类型！");
                return "admin/video/videoTypeAdd";

            }
        }else{
            model.addAttribute("error","请输入类型！");
            return "admin/video/videoTypeAdd";
        }

    }


    @PostMapping(value = "/videoUploadByAdmin")
    public String videoUploadByAdmin(String title,String type, MultipartFile file, HttpServletRequest request,HttpSession session) throws IOException {
        String extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        if(!extName.equals(".mp4")){
            return "admin/video/videoUploadFailed";
        }else{
            Video video = new Video();
            String videoName = file.getOriginalFilename();  //获取上传后的文件名
            // String newVideoName = this.getName(videoName);  //根据上传的文件名重新生成一份新的文件名
//        String path = request.getServletContext().getRealPath("video");
            String path = "D:/upload/video/";
            File videoPath = new File(path, videoName);

            if (!videoPath.getParentFile().exists()) {
                videoPath.getParentFile().mkdirs();
            }


            file.transferTo(videoPath);
            User admin = (User)session.getAttribute("admin");
            video.setAuthor(admin.getUsername());
            video.setPath("/video/" + videoName);
            Timestamp timestamp = new Timestamp(System.currentTimeMillis());
            video.setUploadTime(timestamp);
            video.setTitle(title);
            video.setSize(this.getSize(videoPath));
            video.setType(this.getFileExt(videoName));
            Integer typeId = videoService.selectTypeIdByName(type);
            video.setTypeId(typeId);
            boolean result = videoService.addVideo(video);
            if (result ) {
                return "admin/uploadSuccess";
            }else{
                return "admin/video/videoUploadFailed";
            }
        }
    }

    @GetMapping(value = "/videoPushByIdAndAdmin")
    public String changeRoleById(Integer id) {
        Video video = videoService.getVideoById(id);
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());

        if(video.getPush()==0){
            video.setPush(1);
            video.setPushTime(timestamp);
        }else{
            video.setPush(0);
            video.setPushTime(null);
        }


        boolean result = videoService.addVideoPushById(video);
        if(result) {
            return "forward:/getVideoListByAdmin";
        }

        return "failed";
    }

    //admin查看最新视频
    @GetMapping(value = "/getVideoListByAdmin")
    public String getVideoListByAdmin(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        PageHelper.startPage(num, 5);
        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getVideoList();

        PageInfo pageInfo = new PageInfo(videoList);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/video/videoList";
    }

    //admin查看最热视频
    @GetMapping(value = "/getVideoListByHeatByAdmin")
    public String getVideoListByHeatByAdmin(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        PageHelper.startPage(num, 5);
//        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getVideoListByHeat();

        PageInfo pageInfo = new PageInfo(videoList);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/video/videoList";
    }

    //admin查看自己推送的视频
    @GetMapping(value = "/getVideoListBySystemByAdmin")
    public String getVideoListBySystemByAdmin(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        PageHelper.startPage(num, 5);
        PageHelper.orderBy("pushTime desc");
        List<Video> videoList = videoService.getVideoListBySystem();

        PageInfo pageInfo = new PageInfo(videoList);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/video/videoList";
    }


    @GetMapping(value = "/getVideoList")
    public String getVideoList(@RequestParam(value = "pageNum", defaultValue = "1") Integer num, ModelMap model) {
        PageHelper.startPage(num, 5);
        PageHelper.orderBy("uploadTime desc");
        List<Video> videoList = videoService.getVideoList();

        PageInfo pageInfo = new PageInfo(videoList);
        model.addAttribute("pageInfo", pageInfo);
        return "admin/video/videoList";
    }

    //管理员点击播放按钮，开始播放视频
    @GetMapping(value = "/videoPlayByIdAndAdmin")
    public String videoPlayByIdAndAdmin(Integer id, ModelMap model) {
        Video video = videoService.getVideoById(id);
        model.addAttribute("title", video.getTitle());
        model.addAttribute("path", video.getPath());
        return "admin/video/videoPlay";
    }

    @GetMapping(value = "/deleteVideoById")
    public String deleteVideoById(Integer id, ModelMap model) {

        Video video = videoService.getVideoById(id);

        if (video != null) {
            int result = videoService.deleteVideoById(id);
            if (result > 0) {
                File file = new File("D:/upload"+video.getPath());
                if (file.exists()) {
                    file.delete();
                    return "forward:/getVideoList";
                }
            }
        }
        return "failed";
    }

    @GetMapping(value = "/downloadVideoById")
    public void downloadVideoById(Integer id, HttpServletResponse response) throws IOException {

        Video video = videoService.getVideoById(id);
        String dict = "D:/upload/";
        File file = new File(dict, video.getPath());
        try {
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(video.getPath(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        FileInputStream fis = null;
        OutputStream fos = response.getOutputStream();
        if (file.exists()) {
            fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = fis.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }
        }
        fis.close();
        fos.close();
        videoService.addVideoDownload(id);
    }


    /**
     * 获取文件扩展名
     *
     * @return string
     */
    private String getFileExt(String fileName) {
        return fileName.substring(fileName.lastIndexOf("."));
    }

    /**
     * 依据原始文件名生成新文件名
     *
     * @return
     */
    private String getName(String fileName) {
        Random random = new Random();
        return "" + random.nextInt(10000) + System.currentTimeMillis();

    }

    /**
     * 文件大小，返回kb.mb
     *
     * @return
     */
    private String getSize(File file) {
        String size = "";
        long fileLength = file.length();
        DecimalFormat df = new DecimalFormat("#.00");
        if (fileLength < 1024) {
            size = df.format((double) fileLength) + "BT";
        } else if (fileLength < 1048576) {
            size = df.format((double) fileLength / 1024) + "KB";
        } else if (fileLength < 1073741824) {
            size = df.format((double) fileLength / 1048576) + "MB";
        } else {
            size = df.format((double) fileLength / 1073741824) + "GB";
        }

        return size;

    }
}
